package repository

import (
	"context"
	v1 "server_go/api/v1"
	"server_go/internal/model"
)

type ArticleRepository interface {
	CreateArticle(ctx context.Context, req v1.CreateArticleRequest) (*model.Article, error, uint)
	CreateArticleTag(ctx context.Context, tag uint, articleId uint) (*model.Article_tags, error)
	GetArticleByUserID(ctx context.Context, articleId uint, userId uint) (*model.Article, error)
	DeleteArticle(ctx context.Context, articleId uint) error
	AdminReadArticle(ctx context.Context) (*[]model.Article, error)
	GetTagIdByArticleId(ctx context.Context, articleId uint) ([]uint, error)
	QueryUserByUserId(ctx context.Context, userId uint) ([]model.Article, error)
	GetArticleTagByTagID(ctx context.Context, tagId uint) (*model.Article_tags, error)
	DeleteArticleTagByTagID(ctx context.Context, tagId uint) error
	DeleteArticleTagByArticleId(ctx context.Context, articleId uint) error
}

func NewArticleRepository(
	repository *Repository,
) ArticleRepository {
	return &articleRepository{
		Repository: repository,
	}
}

type articleRepository struct {
	*Repository
}

func (r *articleRepository) GetArticleByUserID(ctx context.Context, articleId uint, userId uint) (*model.Article, error) {
	var article model.Article
	err := r.DB(ctx).Where("id = ? AND user_id = ?", articleId, userId).First(&article).Error
	if err != nil {
		return nil, err
	}
	return &article, nil
}
func (r *articleRepository) CreateArticle(ctx context.Context, req v1.CreateArticleRequest) (*model.Article, error, uint) {
	var article model.Article
	article.Title = req.Title
	article.Content = req.Content
	article.User_id = req.UserId
	err := r.DB(ctx).Create(&article).Error
	return &article, err, article.ID
}
func (r *articleRepository) CreateArticleTag(ctx context.Context, tag uint, articleId uint) (*model.Article_tags, error) {
	var articleTag model.Article_tags
	articleTag.Article_id = articleId
	articleTag.Tag_id = tag
	err := r.DB(ctx).Create(&articleTag).Error
	return &articleTag, err
}
func (r *articleRepository) DeleteArticle(ctx context.Context, articleId uint) error {
	return r.DB(ctx).Where("id = ?", articleId).Delete(&model.Article{}).Error
}
func (r *articleRepository) AdminReadArticle(ctx context.Context) (*[]model.Article, error) {
	var articles []model.Article
	err := r.DB(ctx).Find(&articles).Error
	return &articles, err
}
func (r *articleRepository) GetTagIdByArticleId(ctx context.Context, articleId uint) ([]uint, error) {
	var articleTag []uint
	err := r.DB(ctx).Table("article_tags").Where("article_id = ?", articleId).Pluck("tag_id", &articleTag).Error
	return articleTag, err
}
func (r *articleRepository) QueryUserByUserId(ctx context.Context, userId uint) ([]model.Article, error) {
	var article []model.Article
	err := r.DB(ctx).Where("user_id = ? ", userId).Find(&article).Error
	if err != nil {
		return nil, err
	}
	return article, nil
}
func (r *articleRepository) GetArticleTagByTagID(ctx context.Context, tagId uint) (*model.Article_tags, error) {
	var articleTag model.Article_tags
	err := r.DB(ctx).Where("tag_id = ? ", tagId).First(&articleTag).Error
	if err != nil {
		return nil, err
	}
	return &articleTag, nil
}
func (r *articleRepository) DeleteArticleTagByTagID(ctx context.Context, tagId uint) error {
	return r.DB(ctx).Where("tag_id = ? ", tagId).Delete(&model.Article_tags{}).Error
}
func (r *articleRepository) DeleteArticleTagByArticleId(ctx context.Context, articleId uint) error {
	return r.DB(ctx).Where("article_id = ? ", articleId).Delete(&model.Article_tags{}).Error
}
